module dbc_reader_mod
    use iso_fortran_env,only:real64
    implicit none
    
contains
    !> 用于静态分析,加载位移边界条件, dbc_pos(作用的节点数,2): 第一列是节点,第二列是自由度(1~6)
    !> dbc_val(作用的节点数): 位移值; dbc_num: 作用的节点数
    subroutine load_dbcs_ls(filename,dbc_pos,dbc_val,dbc_num,ierr)
        implicit none
        character(len=*), intent(in) :: filename
        real(real64), allocatable, intent(out) :: dbc_val(:)
        integer, allocatable, intent(out) :: dbc_pos(:,:)
        integer, intent(out) :: dbc_num,ierr
        integer :: fileunit,i,stat

        ierr = 0
        open(newunit=fileunit, file=filename, status='old',&
            action='read', iostat=stat)
        if (stat /= 0) then
            ierr = 1  ! 文件打开失败
            return
        end if
        
        ! 先统计行数
        dbc_num = 0
        do
            read(fileunit, *, iostat=stat)
            if (stat /= 0) exit
            dbc_num = dbc_num + 1
        end do
        
        ! 分配数组内存
        allocate(dbc_pos(dbc_num,2),dbc_val(dbc_num),stat=stat)
        if (stat /= 0) then
            ierr = 2  ! 内存分配失败
            close(fileunit)
            return
        end if
        
        ! 逐行读取坐标数据
        rewind(fileunit)  ! 文件指针回到开头
        do i=1,dbc_num
            read(fileunit,*,iostat=stat) dbc_pos(i,1),dbc_pos(i,2),dbc_val(i)
            if (stat /= 0) then
                deallocate(dbc_pos,dbc_val)
                close(fileunit)
                ierr = 3  ! 数据读取失败
                write(*,'(A,I0,A)') "Error in : bc ",i," read failed!"
                return
            end if 
        end do
        
        ! 关闭文件
        close(fileunit)
    end subroutine load_dbcs_ls
    
    !> 用于模态分析,加载位移边界条件, dbc_pos(作用的节点数,2): 第一列是节点,第二列是自由度(1~6)
    !>  dbc_num: 作用的节点数
    subroutine load_dbcs_nf(filename,dbc_pos,dbc_num,ierr)
        implicit none
        character(len=*), intent(in) :: filename
        integer, allocatable, intent(out) :: dbc_pos(:,:)
        integer, intent(out) :: dbc_num,ierr
        integer :: fileunit,i,stat

        ierr = 0
        open(newunit=fileunit, file=filename, status='old',&
            action='read', iostat=stat)
        if (stat /= 0) then
            ierr = 1  ! 文件打开失败
            return
        end if
        
        ! 先统计行数
        dbc_num = 0
        do
            read(fileunit, *, iostat=stat)
            if (stat /= 0) exit
            dbc_num = dbc_num + 1
        end do
        
        ! 分配数组内存
        allocate(dbc_pos(dbc_num,2),stat=stat)
        if (stat /= 0) then
            ierr = 2  ! 内存分配失败
            close(fileunit)
            return
        end if
        
        ! 逐行读取坐标数据
        rewind(fileunit)  ! 文件指针回到开头
        do i=1,dbc_num
            read(fileunit,*,iostat=stat) dbc_pos(i,1),dbc_pos(i,2)
            if (stat /= 0) then
                deallocate(dbc_pos)
                close(fileunit)
                ierr = 3  ! 数据读取失败
                write(*,'(A,I0,A)') "Error in : bc ",i," read failed!"
                return
            end if 
        end do
        
        ! 关闭文件
        close(fileunit)
    end subroutine load_dbcs_nf

    !> 用于模态分析,加载位移边界条件, dbc_pos(作用的节点数,2): 第一列是节点,第二列是自由度(1~6)
    !> ,dbc_num: 作用的节点数,dbc_val(作用的节点数),dbc_amp(作用的节点数)
    subroutine load_dbcs_dy(filename,dbc_pos,dbc_val,dbc_amp,dbc_num,ierr)
        implicit none
        character(len=*), intent(in) :: filename
        integer, allocatable, intent(out) :: dbc_pos(:,:),dbc_amp(:)
        real(real64), allocatable, intent(out) :: dbc_val(:)
        integer, intent(out) :: dbc_num,ierr
        integer :: fileunit,i,stat

        ierr = 0
        open(newunit=fileunit, file=filename, status='old',&
            action='read', iostat=stat)
        if (stat /= 0) then
            ierr = 1  ! 文件打开失败
            return
        end if
        
        ! 先统计行数
        dbc_num = 0
        do
            read(fileunit, *, iostat=stat)
            if (stat /= 0) exit
            dbc_num = dbc_num + 1
        end do
        
        ! 分配数组内存
        allocate(dbc_pos(dbc_num,2),dbc_val(dbc_num),dbc_amp(dbc_num),stat=stat)
        if (stat /= 0) then
            ierr = 2  ! 内存分配失败
            close(fileunit)
            return
        end if
        
        ! 逐行读取坐标数据
        rewind(fileunit)  ! 文件指针回到开头
        do i=1,dbc_num
            read(fileunit,*,iostat=stat) dbc_pos(i,1),dbc_pos(i,2),dbc_val(i),dbc_amp(i)
            if (stat /= 0) then
                deallocate(dbc_pos,dbc_val,dbc_amp)
                close(fileunit)
                ierr = 3  ! 数据读取失败
                write(*,'(A,I0,A)') "Error in : bc ",i," read failed!"
                return
            end if 
        end do
        
        ! 关闭文件
        close(fileunit)
    end subroutine load_dbcs_dy

end module dbc_reader_mod